#include <jni.h>
#include <malloc.h>
#include <com_wing_tools_rtsp_RtspServer.h>
#include "librtsp/rtsp_server.h"
#include <functional>
#include <string.h>
using namespace std;

JNIEXPORT void JNICALL Java_com_wing_tools_rtsp_RtspServer_rtsp_1server_1config
                   (JNIEnv * env, jclass thiz, jint rtsp_port, jint rtp_port, jint rtcp_port){
    rtsp_server_config(rtsp_port, rtp_port, rtcp_port);
}

JNIEXPORT jlong JNICALL Java_com_wing_tools_rtsp_RtspServer_rtsp_1create
  (JNIEnv * env, jclass thiz, jbyte max_con, jint priority){
    rtsp_handle rtsp = rtsp_create(max_con, priority);
    return (long)rtsp;
}

unsigned char * memfind(unsigned char *buf,unsigned long len,const char *subbuf,unsigned long sublen)
{
    for (unsigned long i=0;i<len-sublen;i++)
    {
        if(memcmp((char *)(buf+i),subbuf,sublen)==0){
            return buf+i;
        }
    }
    return NULL;
}

void HandleH264(unsigned char *pEncodeBuffer,unsigned long dwBufferLen, std::function<void(unsigned char*,unsigned long)> cb)
{
    unsigned char *end,*start=pEncodeBuffer;
    for(;start<pEncodeBuffer+dwBufferLen-3;){
        if(memcmp((char *)start,"\x00\x00\x01",3)==0){
            //one frame
            //start+=3;
            //find the end of frame
            end = memfind(start+3,pEncodeBuffer+dwBufferLen-start-3,"\x00\x00\x01",3);
            if(end==NULL)
            {//this is the last frame
                //HandleH264_1(start,pEncodeBuffer+dwBufferLen-start,time);
                cb(start, pEncodeBuffer+dwBufferLen-start);
                return;
            }else
            {//finded the end of fame
                //HandleH264_1(start,end-start,time);
                cb(start, end-start);
                start=end;
                continue;
            }
        }else{
            start++;
            continue;
        }
    }

}

JNIEXPORT jint JNICALL Java_com_wing_tools_rtsp_RtspServer_rtp_1send_1h264_1ex
        (JNIEnv * env, jclass thiz, jlong rtsp, jbyteArray _buf, jint size){

    rtsp_handle handle = ((rtsp_handle)rtsp);
    jbyte * olddata = (jbyte*) env->GetByteArrayElements(_buf, JNI_FALSE);
    jsize oldsize = env->GetArrayLength(_buf);

    int ret = rtp_send_h264_ex(handle, olddata, oldsize);

//    int ret = 0;
//    HandleH264((unsigned char *) olddata, (unsigned long) oldsize,
//               [&](unsigned char *dt, unsigned long size) {
//                   ret =  rtp_send_h264_ex(handle, (signed char *)dt, size);
//               });

    env->ReleaseByteArrayElements(_buf, olddata, 0);

    return ret;
}

JNIEXPORT void JNICALL Java_com_wing_tools_rtsp_RtspServer_rtsp_1finish
        (JNIEnv * env, jclass thiz,  jlong rtsp){
    rtsp_handle handle = ((rtsp_handle)rtsp);
    rtsp_finish(handle);
}